/*
 * callback.c
 *
 *  Created on: 2011-08-16
 *      Author: Baron Wang
 */

/*
 * The common callback for the testing program, for TCP test.
 */

#include <sys/queue.h>
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include "trans.h"

/*
 * Some buf for log, and for linebuf, etc...
 */
static char        logbuf[512];
struct conn{
    void             *llc;
    int              index;    /* ulc */
    tsock_ep         ep;
    LIST_ENTRY(conn) next;
};

LIST_HEAD(conn_head, conn) conn_list;

int cb_on_new_conn(void *llc, void *ulc, void **out_ulc, tsock_ep *ep){

    printf("%p, %p, %p, %p", llc, ulc, out_ulc, ep);

    LOG(_RTM, "accepting a new socket conn with from %s:%d with ulc %p"
        , ep_to_addr(ep, logbuf, sizeof(logbuf))
        , ep->port
        , ulc);

    struct conn *newconn = malloc(sizeof(struct conn));
    newconn->llc = llc;
    newconn->index = (int)ulc;
    memcpy(&newconn->ep, ep, sizeof(ep));

    LIST_INSERT_HEAD(&conn_list, newconn, next);

    return APP_ACCEPT;
}

int cb_on_connect(void *llc, void *ulc){
    /*
     * user passing the ulc, stores the index of the connection
     * we can see that the User-Level-Context can be general purposed.
     */
    LOG(_RTM, "get connected with ulc %p", ulc);
    return 0;
}

int cb_on_timer(int id, void *llc, void *ulc){
    LOG(_RTM, "timeout with ulc %p", ulc);
    return 0;
}

int cb_read_tcp(void *llc, void* ulc, char* buf, int len){

    char buff[512];
    snprintf(buff, len + 1, "%s", buf);
    LOG(_RTM, "recv a tcp msg \"%s\", len %d. from ulc %p", buff, len, ulc);
    return 0;

}

int cb_close(void *llc, void *ulc, int err){

    struct conn *closed_conn;
    LIST_FOREACH(closed_conn, &conn_list, next){
        if(closed_conn->llc == llc){
            /* TODO */

        }
    }

    LOG(_RTM, "socket closed, %p", ulc);
    return 0;
}

int cb_read_udp(void *llc, void* ulc, tsock_ep *from, tsock_ep *to, char* buf, int len){

    char buff[512];

    snprintf(buff, len, "%s", buf);
    LOG(_RTM, "recv a udp msg \"%s\", len %d. from ulc %p", buff, len, ulc);

    /*
    if(!is_ep_init(&remote_ep)){
        memcpy(&remote_ep, from, sizeof(tsock_ep));
    } */
    return 0;
}

int cb_sock_err(void *llc, void *ulc, int err){
    LOG(_RTM, "socket error");
    return 0;
}

int cb_listen_err(void *llc, void *ulc, int err){
    LOG(_RTM, "listen error");
    return 0;
}

int cb_conn_err(void *llc, void *ulc, int err){
    LOG(_RTM, "connection error");
    return 0;
}
